#include "mystarwidget.h"
#include "ui_mystarwidget.h"
#include <QDebug>

//光照参数
extern GLfloat lightAmbient[];
extern GLfloat lightdiffuse[];
extern GLfloat lightPos[];

MyStarWidget::MyStarWidget(QWidget *parent) :
    QGLWidget(parent),
    ui(new Ui::MyStarWidget)
{
    ui->setupUi(this);
    setGeometry(200,200,600,600);
    mMove_z=-5;
    mRotate_x=mRotate_y=mRotate_z=0;
}

MyStarWidget::~MyStarWidget()
{
    delete ui;
}


void MyStarWidget::initializeGL()
{
    //纹理
    LoadGLTextures();
    glEnable(GL_TEXTURE_2D);
    //阴影
    glShadeModel(GL_SMOOTH);         //shade model
    glClearColor(0,0,0,0.5);   //clear color depth

    glClearDepth(1.0);
    glEnable(GL_DEPTH_TEST);        //enable depth
    glDepthFunc(GL_LEQUAL);         //depth func

    glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); //perspective hint

    //光照
    LightInit();
    //混合
    BlendInit();

    //剔除表面
    //glEnable(GL_CULL_FACE);
    for(int i=0;i<100;i++)
    {
        mStars[i].angle=0;
        mStars[i].dist=(float(i)/100)*5;
        mStars[i].r=rand()%256;
        mStars[i].g=rand()%256;
        mStars[i].b=rand()%256;
    }

}

void MyStarWidget::resizeGL(int w, int h)
{
    glViewport(0,0,(GLint)w,(GLint)h);     //viewport
    //glMatrixMode(GL_PROJECTION);            //matrix mode
    //glLoadIdentity();                       //reset

    glMatrixMode(GL_PROJECTION);
    glFrustum(-2,2,-(float)h/w*2,(float)h/w*2,1,10);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void MyStarWidget::DrawStar()
{
    float spin=0;
    glBindTexture(GL_TEXTURE_2D,mTexture[0]);

    for(int i=0;i<100;i++)
    {
        glLoadIdentity();
        glTranslatef(0,0,mMove_z);

        glRotatef(mRotate_x,1,0,0);
        glRotatef(mRotate_y,0,1,0);
        glRotatef(mRotate_z,0,0,1);

        glRotatef(mStars[i].angle,0,1,0);
        glTranslatef(mStars[i].dist,0,0);

        glRotatef(-mStars[i].angle,0,1,0);
        glRotatef(-mRotate_z,0,0,1);
        glRotatef(-mRotate_y,0,1,0);
        glRotatef(-mRotate_x,1,0,0);

        glColor4ub(mStars[i].r,mStars[i].g,mStars[i].b,255);
        glBegin(GL_QUADS);
            glTexCoord2f(0,0);  glVertex3f(-1,-1,1);
            glTexCoord2f(1,0);  glVertex3f(1,-1,1);
            glTexCoord2f(1,1);  glVertex3f(1,1,1);
            glTexCoord2f(0,1);  glVertex3f(-1,1,1);
        glEnd();
        glRotatef(spin,0,0,1);
        glBegin(GL_QUADS);
            glTexCoord2f(0,0);  glVertex3f(-1,-1,1);
            glTexCoord2f(1,0);  glVertex3f(1,-1,1);
            glTexCoord2f(1,1);  glVertex3f(1,1,1);
            glTexCoord2f(0,1);  glVertex3f(-1,1,1);
        glEnd();
        spin+=1;
        mStars[i].angle=float(i)/100;
        mStars[i].dist-=0.01;
        if(mStars[i].dist<0)
        {
            mStars[i].dist+=5;
        }
    }

}

void MyStarWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);   //clear
    DrawStar();
}
void MyStarWidget::keyPressEvent(QKeyEvent* e)
{
    switch(e->key())
    {
    case Qt::Key_Left:
        mRotate_z-=10;
        break;
    case Qt::Key_Right:
        mRotate_z+=10;
        break;
    case Qt::Key_Up:
        mRotate_x-=10;
        break;
    case Qt::Key_Down:
        mRotate_x+=10;
        break;
    case Qt::Key_Plus:
        mMove_z+=1;
        break;
    case Qt::Key_Minus:
        mMove_z-=1;
        break;
    case Qt::Key_L:
    {
        GLboolean light;
        glGetBooleanv(GL_LIGHTING,&light);
        light=!light;
        if(light)
            glEnable(GL_LIGHTING);
        else
            glDisable(GL_LIGHTING);
    }
    case Qt::Key_B:
    {
        GLboolean blend;
        glGetBooleanv(GL_BLEND,&blend);
        blend=!blend;
        if(blend)
        {
            glEnable(GL_BLEND);
            glDisable(GL_DEPTH_TEST);
        }
        else
        {
            glDisable(GL_BLEND);
            glEnable(GL_DEPTH_TEST);
        }
    }
    }
    updateGL();
}


int MyStarWidget::LoadGLTextures()
{
    QImage image("G:\\Project\\OpenGL\\star.jpg");
    if(image.isNull())
    {
        qDebug()<<"Image Is Null";
        return 1;
    }
    else
        qDebug()<<"w:"<<image.width();
    QImage Tex=QGLWidget::convertToGLFormat(image);

    glGenTextures(3,mTexture);

    glBindTexture(GL_TEXTURE_2D,mTexture[0]);
    glTexImage2D(GL_TEXTURE_2D,0,3,image.width(),image.height(),0,GL_RGBA,GL_UNSIGNED_BYTE,Tex.bits());
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);

    glBindTexture(GL_TEXTURE_2D,mTexture[1]);
    glTexImage2D(GL_TEXTURE_2D,0,3,image.width(),image.height(),0,GL_RGBA,GL_UNSIGNED_BYTE,Tex.bits());
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

    glBindTexture(GL_TEXTURE_2D,mTexture[2]);
    glTexImage2D(GL_TEXTURE_2D,0,3,image.width(),image.height(),0,GL_RGBA,GL_UNSIGNED_BYTE,Tex.bits());
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NICEST);
}
void MyStarWidget::LightInit()
{
    //光照
    glLightfv(GL_LIGHT1,GL_AMBIENT,lightAmbient);
    glLightfv(GL_LIGHT1,GL_DIFFUSE,lightdiffuse);
    glLightfv(GL_LIGHT1,GL_POSITION,lightPos);
    glEnable(GL_LIGHT1);
}
void MyStarWidget::BlendInit()
{
    //glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
    glColor4f(1,1,1,0.5);
    //在深度缓存启用时，您应该将透明图形按照深度进行排序，并在全部场景绘制完毕之后再绘制这些透明物体。否则您将得到不正确的结果。我知道某些时候这样做是很令人痛苦的，但这是正确的方法。
    glBlendFunc(GL_ONE,GL_ZERO);

}
